﻿package keyfun.loaders
{
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	import flash.display.BitmapData;
	import flash.display.Bitmap;
	
	import keyfun.events.ImageLoaderEvent;
	import keyfun.utils.ResizeUtil;

	public class ImageLoader extends Sprite
	{
		public static const ALIGN_CENTER:String = "center";
		public static const ALIGN_TOP_LEFT:String = "top-left";
		
		public static const SCALE_RATIO:String = "ratio";
		public static const SCALE_EXACT:String = "exact";
		public static const SCALE_NONE:String = "none";
		
		private var url:String;
		private var loader:Loader;
		private var imgWidth:Number = 100;
		private var imgHeight:Number = 100;
		private var align:String = ALIGN_TOP_LEFT;
		private var scaleMode:String = SCALE_RATIO;
		
		private var bytesTotal:Number;
		private var bytesLoaded:Number;

		public function ImageLoader(parUrl:String="", parAlign:String=ALIGN_TOP_LEFT, parScaleMode:String=SCALE_NONE, parWidth:Number=100, parHeight:Number=100)
		{	
			url = parUrl;
			
			if (url == "")
			{
				trace("Bad URL");
			}
			
			imgWidth = parWidth;
			imgHeight = parHeight;
			align = parAlign;
			scaleMode = parScaleMode;
			
			if (align == "")
			{
				align = ALIGN_TOP_LEFT;
			}
			
			if (scaleMode == "")
			{
				scaleMode = SCALE_NONE;
			}
			
			loader = new Loader();
			addEvents(loader.contentLoaderInfo);
			var request:URLRequest = new URLRequest(url);
			loader.load(request);
			addChild(loader);
		}

		private function addEvents(dispatcher:IEventDispatcher):void
		{
			dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
			dispatcher.addEventListener(Event.COMPLETE, completeHandler);
			dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
		}
		
		private function removeEvents(dispatcher:IEventDispatcher):void
		{
			dispatcher.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
			dispatcher.removeEventListener(Event.COMPLETE, completeHandler);
			dispatcher.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
		}
		
		private function ioErrorHandler(e:IOErrorEvent):void 
		{
    		trace("====> ioErrorHandler: " + e);
			removeEvents(loader.contentLoaderInfo);
			removeChild(loader);
			dispatchEvent(new ImageLoaderEvent(ImageLoaderEvent.ON_ERROR));
		} 

		private function completeHandler(e:Event):void
		{
			removeEvents(loader.contentLoaderInfo);
			
			if(scaleMode == SCALE_RATIO)
			{
				ResizeUtil.resizeObject(loader, imgWidth, imgHeight);
			}
			else if(scaleMode == SCALE_EXACT)
			{
				loader.width = imgWidth;
				loader.height = imgHeight;
			}
			else
			{
				// scale none
			}
			
			if(align == ALIGN_CENTER)
			{
				loader.x = -loader.width / 2;
				loader.y = -loader.height / 2;
			}
			Bitmap(loader.content).smoothing = true;
			
			dispatchEvent(new ImageLoaderEvent(ImageLoaderEvent.ON_COMPLETE));
		}
		
		private function progressHandler(e:ProgressEvent):void
		{
			bytesLoaded = e.bytesLoaded;
			bytesTotal = e.bytesTotal;
			dispatchEvent(new ImageLoaderEvent(ImageLoaderEvent.ON_LOADING, bytesLoaded, bytesTotal));
		}
		
		///////////////////////////////
		// Public function
		//////////////////////////////

		public function getBytesTotal():Number
		{
			return bytesTotal;
		}

		public function getBytesLoaded():Number
		{
			return bytesLoaded;
		}
		
		public function getLoader():Loader
		{
			return loader;
		}
		
		public function getBitmapData():BitmapData
		{
			return BitmapData(loader.content["bitmapData"]);
		}
		
		public function getBitmap():Bitmap
		{
			return(Bitmap(loader.content));
		}
		
		public function getBitmapDataClone():BitmapData
		{
			return BitmapData(loader.content["bitmapData"]).clone();
		}
		
		public function dispose():void
		{
			getBitmapData().dispose();
			loader = null;
		}
	}
}